Software programs are commonly written in a high-level programming language, such as VISUAL BASIC, C++, COBOL, Pascal, Smalltalk, or the like. The high-level language statements or instructions of the program (e.g., source code) are then translated or compiled into coded instructions (e.g., native or object code), which are executable by the computer. Typically, a software program known as a compiler is used for this translation. Processes for compiling source code into executable object or native code are well known in the art. The compiler initially performs lexical analysis on the source code to separate the source code into various lexical structures of the programming language (generally known as tokens), such as keywords, identifiers, operator symbols, punctuation, and the like. Syntactical analysis is then performed in which the compiler groups the tokens into various syntax structures of the programming language, such as expressions, declaration statements, loop statements, procedure calls, and the like. Thereafter, the compiler generates and optimizes code for each of these structures.
Such source code program representations may include declarations and implementations which the compiler must associate. For instance, a source program may include a function or method declaration in an interface being implemented by a class. The class implementing the interface may in turn provide an implementation for the declared function or method. The compiler associates the declaration and the implementation in generating native code for the program. Compilers typically employ one or more association rules particular to the source code language of interest in associating such source code declarations and implementations.
Where the programmer writes source code which is vague or ambiguous as to what implementation is to be associated with a particular declaration, the compiler typically generates a compiler error, which the programmer must address before the program can be successfully compiled. In this case, the compiler employs one or more association or disambiguation rules (e.g., signature matching, calling context, etc.), or criteria in determining when to generate such an error. Such association or disambiguation rules are generally specific to a particular source code language, as the syntax and semantics of source code languages varies greatly. Thus, the association rules appropriate for one source code language may not be (e.g., and typically are not) adaptable to properly associated declarations and implementations in another source code language.
Recent developments in programming technologies have provided common language runtime systems, in which programs and software modules created in a variety of source code programming languages may be executed, and/or combined to form new programs. The programmer compiles source code (e.g., written in a high-level programming language) into an intermediate language representation of the source code (e.g., intermediate language or “IL” code) using a source compiler. In this case, the source compiler does not generate native (e.g., machine executable) code, but instead provides only the IL representation. The runtime system then receives the IL code representation from the source compiler, and performs an IL to native code conversion, which may be accomplished using a just-in-time (JIT) compiler. This IL to native code conversion (e.g., JIT compilation) may include combining software components (e.g., modules, objects, etc.) from a variety of sources, which may have been originally coded in different high-level (e.g., source code) languages.
Although the IL representation defines the declarations and implementations, the IL code does not define the associations therebetween. The combination of such software components in the runtime system thus includes associating declarations with implementations. Before JIT compilation, all such associations must be understood by the runtime in order to generate the correct native implementation. This is because ambiguities in the association between a declaration and an implementation may not be easily addressable at the point in time when the JIT compilation occurs. For instance, name collisions in declarations and implementations may not be correctable in the source code, since the runtime system receives only the IL program representation from the source compiler(s). The point where JIT compilation occurrs may be too late to provide the original programmer with a compiler error. Thus, previous source language compilers disambiguate declarations according to their rules, and the newer common language runtime systems must make the same associations. In addition, the common language runtime needs to understand the cross language differences. Furthermore, the runtime system may be able to implement a number of disambiguation or association rules, but cannot support all such association rules for all source languages.
Thus, even where a common language runtime system employs one or more such default association rules (e.g., signature matching, name matching, etc.), the runtime system cannot reliably associate every declaration/implementation pair. Moreover, such ambiguities may result from the combination of such IL code components, which were originally generated by different programmers in different source code languages. In this case, the source compilers may not even be able to detect such ambiguities. Thus, improved methods and systems are needed to reduce the possibility of ambiguities in association between declarations and implementations in such common language runtime systems.